{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    },
    "tags": [
     "ignore_me"
    ]
   },
   "source": [
    "<img src=\"images/strathsdr_banner.png\" align=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    },
    "tags": [
     "ignore_me"
    ]
   },
   "source": [
    "# RFSoC QPSK Transceiver with Voila\n",
    "----\n",
    "\n",
    "<div class=\"alert alert-box alert-info\">\n",
    "Please use Jupyter Labs http://board_ip_address/lab for this notebook.\n",
    "</div>\n",
    "\n",
    "The RFSoC QPSK demonstrator was developed by the [University of Strathclyde](https://github.com/strath-sdr/rfsoc_sam). This notebook is specifically for Voila dashboards. If you would like to see an overview of the QPSK demonstrator, see this [notebook](rfsoc_qpsk_demonstrator.ipynb) instead.\n",
    "\n",
    "## Table of Contents\n",
    "* [Introduction](#introduction)\n",
    "* [Running this Demonstration](#running-this-demonstration)\n",
    "* [The Voila Procedure](#the-voila-procedure)\n",
    "    * [Import Libraries](#import-libraries)\n",
    "    * [Initialise Overlay](#initialise-overlay)\n",
    "    * [Dashboard Display](#dashboard-display)\n",
    "* [Conclusion](#conclusion)\n",
    "\n",
    "## References\n",
    "* [Xilinx, Inc, \"USP RF Data Converter: LogiCORE IP Product Guide\", PG269, v2.3, June 2020](https://www.xilinx.com/support/documentation/ip_documentation/usp_rf_data_converter/v2_3/pg269-rf-data-converter.pdf)\n",
    "\n",
    "## Revision History\n",
    "* **v1.0** | 16/02/2021 | Voila RFSoC QPSK demonstrator\n",
    "\n",
    "----\n",
    "\n",
    "## Introduction <a class=\"anchor\" id=\"introduction\"></a>\n",
    "The ZCU111 platform and XM500 development board can be configured as a simple QPSK transceiver. The RFSoC QPSK demonstrator uses the RFSoC's RF Data Converters (RF DCs) to transmit and receive QPSK modulated waveforms. This notebook is specifically for running the QPSK demonstrator using Voila dashboards. Follow the instructions outlined in [Running this Demonstration](#running-this-demonstration) to learn more.\n",
    "\n",
    "### Hardware Setup <a class=\"anchor\" id=\"hardware-setup\"></a>\n",
    "Your RFSoC2x2 development board can be configured to host one QPSK transceiver channel. To setup your board for this demonstration, you can connect a channel in loopback as shown in [Figure 1](#fig-1).\n",
    "\n",
    "The default loopback configuration is connected as follows:\n",
    "* Channel 0: DAC2 to ADC2\n",
    "\n",
    "Use the image below for further guidance.\n",
    "\n",
    "<a class=\"anchor\" id=\"fig-1\"></a>\n",
    "<figure>\n",
    "<img src='images/rfsoc2x2_setup.jpg' height='50%' width='50%'/>\n",
    "    <figcaption><b>Figure 1: RFSoC2x2 development board setup in loopback mode.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "**Do not** attach an antenna to any SMA interfaces labelled DAC.\n",
    "\n",
    "<div class=\"alert alert-box alert-danger\">\n",
    "<b>Caution:</b>\n",
    "    In this demonstration, we generate tones using the RFSoC development board. Your device should be setup in loopback mode. You should understand that the RFSoC platform can also transmit RF signals wirelessly. Remember that unlicensed wireless transmission of RF signals may be illegal in your geographical location. Radio signals may also interfere with nearby devices, such as pacemakers and emergency radio equipment. Note that it is also illegal to intercept and decode particular RF signals. If you are unsure, please seek professional support.\n",
    "</div>\n",
    "\n",
    "----\n",
    "\n",
    "## Running this Demonstration <a class=\"anchor\" id=\"running-this-demonstration\"></a>\n",
    "Voila can be used to execute the QPSK demonstrator and ignore all of the markdown and code cells typically found in a normal Jupyter notebook. The Voila dashboard can be launched following the instructions below:\n",
    "\n",
    "* Click on the \"Open with Voila Gridstack in a new browser tab\" button at the top of the screen:\n",
    "\n",
    "<figure>\n",
    "<img src='images/open_voila.png' height='50%' width='50%'/>\n",
    "</figure>\n",
    "\n",
    "After the new tab opens the kernel will start and the notebook will run. Only the QPSK Demonstrator will be displayed. The initialisation process takes around 1 minute.\n",
    "\n",
    "## The Voila Procedure <a class=\"anchor\" id=\"the-voila-procedure\"></a>\n",
    "Below are the code cells that will be ran when Voila is called. The procedure is fairly straight forward. Load the rfsoc-qpsk library, initialise the overlay, and display the QPSK demonstrator. All you have to ensure is that the above command is executed in the terminal and you have launched a browser tab using the given address. You do not need to run these code cells individually to create the voila dashboard.\n",
    "\n",
    "### Import Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "outputs": [],
   "source": [
    "from rfsoc_qpsk.qpsk_overlay import QpskOverlay"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    },
    "tags": [
     "ignore_me"
    ]
   },
   "source": [
    "### Initialise Overlay"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "outputs": [],
   "source": [
    "qpsk = QpskOverlay(dark_theme=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    },
    "tags": [
     "ignore_me"
    ]
   },
   "source": [
    "### Dashboard Display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": 0,
        "height": 16,
        "hidden": false,
        "row": 0,
        "width": 12
       }
      }
     }
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "qpsk.qpsk_demonstrator_application()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    },
    "tags": [
     "ignore_me"
    ]
   },
   "source": [
    "## Conclusion\n",
    "This notebook has presented a QPSK demonstrator for the ZCU111 development board. The demonstration used Voila to enable rapid dashboarding for visualisation and control."
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "extensions": {
   "jupyter_dashboards": {
    "activeView": "grid_default",
    "version": 1,
    "views": {
     "grid_default": {
      "cellMargin": 2,
      "defaultCellHeight": 60,
      "maxColumns": 12,
      "name": "grid",
      "type": "grid"
     }
    }
   }
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
